Field of the Invention
The present invention relates to software unit testing and more particularly to the use of mock objects during software unit testing.
Description of the Related Art
Unit testing is a software development process in which the smallest testable portions of a software application are individually and independently scrutinized for proper operation. Unit testing can be either automated or performed manually, however, in most cases, unit testing is performed through an automated process of a testing tool. Of note, unit testing is a stage of “Extreme Programming” in which the software development lifecycle requires continual testing and revision.
Unit testing involves only those characteristics that are vital to the performance of the unit under test. As such, unit testing encourages developers to modify source code without the immediate concern of how any imposed changes to the source code might affect the operability of other units of source code or the software application as a whole. Once all of the units in a software application have been found to execute in a most efficient and error-free manner possible, larger components of the software application can be evaluated by means of integration testing.
Of note, unit testing has become widely accepted as a “best practice” for software development. For every object developed by a developer, a corresponding automated test class must be developed to include methods that test the object, calling its various public methods with various parameters and ensuring that the values returned are appropriate. It will be recognized then that in respect to simple data or service objects, writing unit tests can be straightforward. However, many objects rely on other objects or layers of infrastructure. Consequently, when it comes to testing these types of objects, unit testing can become expensive, impractical, or inefficient.
For example, to unit test an object that uses a database, it may be burdensome to install, configure, and seed a local copy of the database, run the unit tests, and then remove the database. Mock objects provide a solution to this dilemma. A mock object conforms to the interface of the real object under test, but contains only enough program code to fool the tested object and track its behavior. For example, a database connection for a particular unit test might record the query while always returning the same hardwired result. As long as the class being tested behaves as expected, the object under test will not notice the difference, and the unit test can check that the proper query was emitted.
The use of mock objects, however, is not without its complications. In this regard, when an interface to which a mock object conforms changes, the mock object implementation will fail to compile unless the mock object also changes. The necessity to change the mock object, however, is often not obvious to the developer who changes the interface, since the changing developer is not likely to know all components that have included mock versions with corresponding test suites. Consequently, broken builds, test failures and time wasting can be the undesirable result.